package org.adorsys.aderp.jpa.impl;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.beans.factory.BeanFactory;

public class OneToManyRelationshipInfoBuilder {
	
	public static List<OneToManyRelationShipInfo> build(
			Class<?> klass, BeanFactory beanFactory){
		List<Field> fields = FieldResolver.extractField(klass, new OneToManyAnnotationFilter());
		List<OneToManyRelationShipInfo> result = new ArrayList<OneToManyRelationShipInfo>();
		for (Field field : fields) {
			OneToManyRelationShipInfo oneToManyRelationShipInfo = 
					processAnnotatedField(klass, field,beanFactory);
			if(oneToManyRelationShipInfo!=null)
				result.add(oneToManyRelationShipInfo);
		}
		return result;
	}	
	
	private static OneToManyRelationShipInfo processAnnotatedField(Class<?> klass, 
			Field field, BeanFactory beanFactory)
	{
		Class<?> fieldType = field.getType();
		
		// First we support only collections
		if(!Collection.class.isAssignableFrom(fieldType)) return null;
		
		ParameterizedType genericType = (ParameterizedType) field.getGenericType();
		Type[] actualTypeArguments = genericType.getActualTypeArguments();
		
		// Accept no parameterless collections
		if(actualTypeArguments.length==0) return null;
		
		Class<?> type = (Class<?>)actualTypeArguments[0];
		
		// check if field is not a primitive
		if(type.isPrimitive() || type.isEnum()) return null;
		
		// check if field is not a Map Type. We don't support map type now
		if(type.getPackage().getName().startsWith("java")) return null;// primitive wrappers
		
		Method getterMethod = FieldResolver.getterMethod(field, klass);
		return new OneToManyRelationShipInfo(field, getterMethod, beanFactory, type);
	}
}
